package com.smart.io;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;


public class OSFileIO {

  static byte[] data="123456789\n".getBytes(StandardCharsets.UTF_8);
  static String path="/root/sysio/out.txt";
//  static String path="d:/tmp/sysio/out.txt";
  static int LEN=100000;

  public static void main(String[] args) throws IOException {
    long start=System.nanoTime();

    switch (args[0]){
      case "basic":
        testBasicFileIO();
        break;
      case "buffer":
        testBufferedFileIO();
        break;
      case "force":
        testRandomAccessFileWrite01();
        break;
      case "mmap":
        testRandomAccessFileWrite02();
        break;
      default:
        break;
    }
    long end=System.nanoTime();
    System.out.println("cost:"+(end-start) / 1000 / 1000 +"ms");
  }

  private static void testRandomAccessFileWrite02() throws IOException {
    RandomAccessFile raf=new RandomAccessFile(path+".mmap","rw");
    FileChannel rafChannel=raf.getChannel();
    MappedByteBuffer map=rafChannel.map(FileChannel.MapMode.READ_WRITE,0,data.length * LEN);
    for (int i=0;i<LEN;i++){
      map.put(data);
//      map.force();
    }

    raf.close();
  }

  private static void testRandomAccessFileWrite01() throws IOException {
    RandomAccessFile raf=new RandomAccessFile(path+".force","rw");
    for (int i=0;i<LEN;i++){
      raf.write(data);
      raf.getChannel().force(true);
    }

    raf.close();
  }

  private static void testBufferedFileIO() throws IOException {
    File file=new File(path+".buffer");
    BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(file));
    for(int i=0;i<LEN;i++){
      out.write(data);
      out.flush();
    }

    out.close();
  }

  private static void testBasicFileIO() throws IOException {
    File file=new File(path+".basic");
    FileOutputStream out=new FileOutputStream(file);
    for(int i=0;i<LEN;i++){
      out.write(data);
      out.flush();
    }

    out.close();
  }

}
